package com.wingice.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wingice.common.page.EntityPageBean;
import com.wingice.spring.security.common.utils.SecurityUtils;
import com.wingice.spring.security.model.KnifeUser;
import com.wingice.system.constant.SecurityConstant;
import com.wingice.system.entity.SysRole;
import com.wingice.system.entity.SysRoleResource;
import com.wingice.system.entity.SysRoleUser;
import com.wingice.system.exception.SysBusinessCode;
import com.wingice.system.exception.SysBusinessException;
import com.wingice.system.mapper.SysRoleMapper;
import com.wingice.system.service.SysRoleResourceService;
import com.wingice.system.service.SysRoleService;
import com.wingice.system.service.SysRoleUserService;
import com.wingice.utils.transfer.TransferUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 表基础信息 服务实现类
 * </p>
 *
 * @author 胡昊
 * @since 2020-07-23
 */
@Transactional
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Resource
    private SysRoleResourceService sysRoleResourceService;
    @Resource
    private SysRoleUserService sysRoleUserService;

    @Override
    public Boolean insertSysRole(SysRole sysRole) {
        //校验roleKey是否有重复
        if (count(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleKey, sysRole.getRoleKey())) > 0) {
            throw new SysBusinessException(SysBusinessCode.ROLE_KEY_CONFLICT_ERROR);
        }
        save(sysRole);
        //建立角色与当前用户关联
        final SysRoleUser sysRoleUser = new SysRoleUser();
        sysRoleUser.setRoleId(sysRole.getId());
        sysRoleUser.setUserId(SecurityUtils.getUser().getId());
        sysRoleUserService.save(sysRoleUser);
        return true;
    }

    @Override
    public Boolean updateSysRole(SysRole sysRole) {
        //校验roleKey是否有重复
        if (count(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleKey, sysRole.getRoleKey()).ne(SysRole::getId, sysRole.getId())) > 0) {
            throw new SysBusinessException(SysBusinessCode.ROLE_KEY_CONFLICT_ERROR);
        }
        //校验是否有权限操作角色
        final KnifeUser knifeUser = SecurityUtils.getUser();
        final List<SysRole> userRoleList = sysRoleUserService.listUserRole(knifeUser.getId());
        final SysRole superAdminRole = getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleKey, SecurityConstant.KNIFE_SUPER_ADMIN));
        if (CollectionUtils.isEmpty(userRoleList) || (!userRoleList.contains(superAdminRole)
                && !userRoleList
                .stream()
                .map(SysRole::getId)
                .collect(Collectors.toList())
                .contains(sysRole.getId()))) {
            throw new SysBusinessException(SysBusinessCode.ROLE_PERMISSION_DENY);
        }
        return updateById(sysRole);
    }

    @Override
    public Boolean deleteBatch(List<String> idList) {
        long innerRoleNum = count(Wrappers.<SysRole>lambdaQuery().in(SysRole::getId, idList).eq(SysRole::getRoleType, 1));
        if (innerRoleNum > 0) {
            throw new SysBusinessException(SysBusinessCode.INNER_ROLE_DELETE_FORBIDDEN);
        }
        //校验是否有权限操作角色
        final KnifeUser knifeUser = SecurityUtils.getUser();
        final List<SysRole> userRoleList = sysRoleUserService.listUserRole(knifeUser.getId());
        final SysRole superAdminRole = getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleKey, SecurityConstant.KNIFE_SUPER_ADMIN));
        if (CollectionUtils.isEmpty(userRoleList) || (!userRoleList.contains(superAdminRole)
                && !userRoleList
                .stream()
                .map(SysRole::getId)
                .collect(Collectors.toList())
                .containsAll(idList))) {
            throw new SysBusinessException(SysBusinessCode.ROLE_PERMISSION_DENY);
        }
        //删除角色与资源关联
        sysRoleResourceService.remove(Wrappers.<SysRoleResource>lambdaQuery().in(SysRoleResource::getRoleId, idList));
        //删除角色与用户关联
        sysRoleUserService.remove(Wrappers.<SysRoleUser>lambdaQuery().in(SysRoleUser::getRoleId, idList));
        return removeByIds(idList);
    }

    @Override
    public Page<SysRole> pageSysRole(EntityPageBean<SysRole> entityPageBean) {
        final KnifeUser knifeUser = SecurityUtils.getUser();
        final List<SysRole> userRoleList = sysRoleUserService.listUserRole(knifeUser.getId());
        if (CollectionUtils.isEmpty(userRoleList)) {
            return new Page<>();
        }
        final SysRole superAdminRole = getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleKey, SecurityConstant.KNIFE_SUPER_ADMIN));
        return page(TransferUtils.pageEntityToPage(entityPageBean), Wrappers.<SysRole>lambdaQuery()
                .in(!userRoleList.contains(superAdminRole), SysRole::getId, userRoleList.stream().map(SysRole::getId).collect(Collectors.toList()))
                .eq(StringUtils.hasText(entityPageBean.getEntity().getId()), SysRole::getId, entityPageBean.getEntity().getId())
                .like(StringUtils.hasText(entityPageBean.getEntity().getRoleKey()), SysRole::getRoleKey, entityPageBean.getEntity().getRoleKey())
                .like(StringUtils.hasText(entityPageBean.getEntity().getName()), SysRole::getName, entityPageBean.getEntity().getName()));
    }
}
